/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu.
 *
 * Copyright (C) 2005-2011  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.ccvisu.graph;

import java.util.EnumMap;
import java.util.Map;

/**
 * Allows different parts of the program to set their own visibility.
 * The option with the highest priority is used.
 */
public class NameVisibility {

  /** Fallback if no visibilities are set. */
  private static Visibility DEFAULT_VISIBILITY = Visibility.HIDE;

  private Map<Priority, Visibility> visibility;

  private enum Visibility {
    SHOW,
    HIDE
  }

  /**
   * Denoting different parts of the system that can independently set or unset
   * the visibility of names.
   *
   * Priority is determined by the sequence of definition, i.e. constants
   * defined first have a higher priority then those defined later on.
   */
  public enum Priority {
    /** Manual setting of the name visibility. */
    MANUAL,
    /** Filtering of names using the find mechanism. */
    FIND,
    DEPDEGREE,
    GROUPS,
    /** Set by the GUI for all nodes. */
    GUISET,
    /**
     * Default value set at startup or creation (may be option read
     * from input file or set via command line).
     */
    STARTUP
  }

  public NameVisibility() {
    visibility = new EnumMap<Priority, Visibility>(Priority.class);
  }

  /** Copy constructor. */
  public NameVisibility(NameVisibility vis) {
    this.visibility = new EnumMap<Priority, Visibility>(vis.visibility);
  }

  /**
   * Set the visibility for a given priority.
   *
   * @param prio The Priority for which visibility is to be set.
   * @param visible true, if the name is to be visible for the given priority,
   * false otherwise.
   */
  public void setVisibility(Priority prio, boolean visible) {
    Visibility visibilityStatus = visible ? Visibility.SHOW : Visibility.HIDE;
    visibility.put(prio, visibilityStatus);
  }

  public void unsetVisibility(Priority prio) {
    visibility.remove(prio);
  }

  /**
   * Resets all visibility priorities of this object
   * to what was set at startup.
   */
  public void reset() {
    visibility.remove(Priority.MANUAL);
    visibility.remove(Priority.FIND);
    visibility.remove(Priority.DEPDEGREE);
    visibility.remove(Priority.GROUPS);
    visibility.remove(Priority.GUISET);
  }

  public boolean isVisible() {
    if (!visibility.isEmpty()) {
      for (Priority priority : Priority.values()) {
        if (visibility.containsKey(priority)) {
          Visibility visibility = this.visibility.get(priority);
          return visibility.equals(Visibility.SHOW);
        }
      }
    }

    return DEFAULT_VISIBILITY.equals(Visibility.SHOW);
  }
}
